package com.niiwoo.civet.trade.service.local.newRefund.dispatch;


import com.alibaba.fastjson.JSON;
import com.niiwoo.asset.org.business.dto.mq.RepaymentSuccessDTO;
import com.niiwoo.civet.base.enums.BorrowProjectTypeEnum;
import com.niiwoo.civet.base.enums.ChannelCodeEnum;
import com.niiwoo.civet.base.enums.OrderTradeSourceEnum;
import com.niiwoo.civet.base.enums.RefundOrderStatusEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.dto.request.RefundRequestDTO;
import com.niiwoo.civet.trade.dto.response.RefundResponseDTO;
import com.niiwoo.civet.trade.enums.RepayStatusEnum;
import com.niiwoo.civet.trade.service.local.newRefund.refundDeal.RefundForRepaymentService;
import com.niiwoo.civet.trade.service.local.refund.CommonLocalService;
import com.niiwoo.tripod.consumer.helper.Exceptions;
import com.niiwoo.tripod.provider.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * 还款本地入口
 * @author wangjun
 */
@Slf4j
@Service
public class RefundDispatchLocalService
{
    @Autowired
    private ProjectBorrowerSummaryMapperExt projectBorrowerSummaryMapperExt;

    @Autowired
    RefundForRepaymentService refundForRepaymentService;

    @Autowired
    protected RefundOrderMapperExt refundOrderMapperExt;

    @Autowired
    protected CommonLocalService commonLocalService;

    @Autowired
    RefundValidateService validateService;
    @Autowired
    ProjectMapperExt projectMapperExt;

    @Autowired
    ReplaceRepaymentConfigMapperExt replaceRepaymentConfigMapperExt;

    @Autowired
    private RefundOrderDetailBizMapperExt refundOrderDetailBizMapperExt;
    @Autowired
    private ProjectBorrowerPlanNewMapperExt projectBorrowerPlanNewMapperExt;

    /**
     * app还款
     * @param refundRequestDTO
     * @return
     */
    public Long refund(RefundRequestDTO refundRequestDTO)
    {
        Assert.notNull(refundRequestDTO,"refundRequestDTO must not be null");
        validateService.validate(refundRequestDTO);

        Project project = projectMapperExt.selectByPrimaryKey(refundRequestDTO.getProjectId());
        Assert.notNull(project,"project must not be null");

        if (ChannelCodeEnum.KAOLA.getChanelCode().equals(project.getChannelCode()) ||
                (refundRequestDTO.getOrderTradeSource() == OrderTradeSourceEnum.APP
                        && (BorrowProjectTypeEnum.ORG_SPEEDLOAN.getValue().equals(project.getType()))))
            Exceptions.throwBizException("TRD_800013","该标的不支持此种方式还款");

        //还款
        RefundOrder refundOrder = refundForRepaymentService.refundForRepayment(
                refundRequestDTO.getProjectId(),
                refundRequestDTO.getOrderTradeSource(),
                refundRequestDTO.getRefundType(),
                commonLocalService.getCurrentDate(),
                refundRequestDTO.getOrgRequestNo());
        log.info("RefundDispatchLocalService->refund result:projectId={},refundOrder={}", refundRequestDTO.getProjectId(),refundOrder);
        return refundOrder.getId();
    }

    public RefundResponseDTO refundQuery(Long refundOrderId){
        return this.refundQuery(refundOrderId,false);
    }

    /**
     * 查询还款
     * @param refundOrderId
     * @return
     */
    public RefundResponseDTO refundQuery(Long refundOrderId,Boolean needDetail)
    {
        Assert.notNull(refundOrderId,"refundOrderId must not be null");

        RefundResponseDTO responseDTO = new RefundResponseDTO();
        RefundOrder refundOrder = refundOrderMapperExt.selectByPrimaryKey(refundOrderId);
        if (refundOrder == null){
            throw new BizException("TRD10001");//订单不存在
        }
        ProjectBorrowerSummary borrowerSummary = projectBorrowerSummaryMapperExt.selectByPrimaryKey(refundOrder.getProjectId());
        Assert.notNull(borrowerSummary,"borrowerSummary must not be null");

        responseDTO.setCode(refundOrder.getStatus());
        responseDTO.setTitle(borrowerSummary.getProjectTitle());
        responseDTO.setCurrentPeriod(borrowerSummary.getCurrentPeriod());
        responseDTO.setTotalPeriod(borrowerSummary.getTotalPeriod());
        responseDTO.setNextRefundDate(borrowerSummary.getRefundDate());
        responseDTO.setRepaidAmount(refundOrder.getRefundingAmount());
        responseDTO.setNeedRepayAmount(refundOrder.getRefundingAmount().subtract(refundOrder.getAmount()));
        if (needDetail){
            log.debug("还款状态查询需要返回订单明细refundOrderId={}",refundOrderId);
//            RefundOrderDTO orderDTO = new RefundOrderDTO();
//            BeanUtils.copyProperties(refundOrder,orderDTO);

            RepaymentSuccessDTO repaymentSuccessDTO = new RepaymentSuccessDTO();
            repaymentSuccessDTO.setRefundOrderId(refundOrder.getId());
            repaymentSuccessDTO.setProjectId(refundOrder.getProjectId());
            repaymentSuccessDTO.setRequestNo(refundOrder.getOrgRequestNo());
            repaymentSuccessDTO.setAmount(refundOrder.getAmount());
            repaymentSuccessDTO.setRefundingAmount(refundOrder.getRefundingAmount());
            repaymentSuccessDTO.setCapital(refundOrder.getCapital());
            repaymentSuccessDTO.setInterest(refundOrder.getInterest());
            repaymentSuccessDTO.setPenaltyFee(refundOrder.getPenaltyFee());
            repaymentSuccessDTO.setManageFee(refundOrder.getManageFee());
            repaymentSuccessDTO.setConsultingFee(refundOrder.getConsultingFee());
            repaymentSuccessDTO.setGuaranteeFee(refundOrder.getGuaranteeFee());
            repaymentSuccessDTO.setTradeSource(refundOrder.getTradeSource());
            repaymentSuccessDTO.setRefundType(refundOrder.getRefundType());
            repaymentSuccessDTO.setOrgId(refundOrder.getOrgId());
            repaymentSuccessDTO.setErrorCode(refundOrder.getErrorCode());
            repaymentSuccessDTO.setErrorMsg(refundOrder.getErrorMessage());
            ProjectBorrowerSummary summary = projectBorrowerSummaryMapperExt.selectByPrimaryKey(refundOrder.getProjectId());
            repaymentSuccessDTO.setNextRefundDate(summary.getRepayStatus().equals(RepayStatusEnum.SETTLEMENT.getCode())? null:summary.getRefundDate());
            repaymentSuccessDTO.setSuccessTime(refundOrder.getSuccessTime());
            repaymentSuccessDTO.setStatus(refundOrder.getStatus());
            log.debug("civet-trade:发送还款消息repaymentSuccessDTO={}", JSON.toJSONString(repaymentSuccessDTO));
            /**
             * repaymentSuccessDTO.setBorrowPlanIdStart(borrowerPlan == null? null:borrowerPlan.getId());
             repaymentSuccessDTO.setNextRefundDate(projectBorrowerSummaryMapperExt.selectByPrimaryKey(refundNotifyDTO.getProjectId()).getRefundDate());
             */
            if (refundOrder.getStatus().equals(RefundOrderStatusEnum.INITIALIZE.getCode())
                    && Byte.valueOf("2").equals(refundOrder.getProcessStatus())){
                repaymentSuccessDTO.setStatus(RefundOrderStatusEnum.HANDLEFAIL.getCode());
            }
            repaymentSuccessDTO.setPeriods(this.getBorrowerPeriods(refundOrder.getProjectId(),refundOrderId));
            //repaymentSuccessDTO.setFundRefundOrderId(refundOrderId);
            //ProjectBorrowerSummary summary = projectBorrowerSummaryMapperExt.selectByPrimaryKey(refundOrder.getProjectId());
            repaymentSuccessDTO.setNextRefundDate(summary.getRepayStatus().equals(RepayStatusEnum.SETTLEMENT.getCode())? null:summary.getRefundDate());
            responseDTO.setRepaymentSuccessDTO(JSON.toJSONString(repaymentSuccessDTO));
        }

        log.debug("civet-trade:查询还款结果:{}", JSON.toJSONString(responseDTO));
        return responseDTO;
    }

    private String getBorrowerPeriods(Long projectId,Long refundOrderId){
        List<RefundOrderDetailBiz> refundOrderDetailBizList = refundOrderDetailBizMapperExt.selectByProjectIdAndRefundOrderId(projectId,refundOrderId);
        Set<Integer> setPeriods = new TreeSet<>((o1, o2) -> {
            if (o1>o2){
                return 1;
            }else if (o1<o2){
                return -1;
            }
            return 0;
        });
        for (RefundOrderDetailBiz biz : refundOrderDetailBizList) {
            if (biz.getCurrentPeriod()>0 ) {
                setPeriods.add(biz.getCurrentPeriod());
            }
        }
        return JSON.toJSONString(setPeriods).replaceAll("\\[","").replaceAll("]","");
    }
    /**
     * 代还
     * @param requestDTO
     * @return
     */
    public Long substituteRefund(RefundRequestDTO requestDTO)
    {
        Assert.notNull(requestDTO,"refundRequestDTO must not be null");
        validateService.validate(requestDTO);

        Project project = projectMapperExt.selectByPrimaryKey(requestDTO.getProjectId());
        Assert.notNull(project,"project must not be null");
        ReplaceRepaymentConfig config = replaceRepaymentConfigMapperExt.selectByPrimaryKey(project.getOrgId());
        if (config == null) Exceptions.throwBizException("TRD_800012","该标的所属机构暂不支持代还");

        //还款
        RefundOrder refundOrder = refundForRepaymentService.refundForReplace(
                requestDTO.getProjectId(),
                requestDTO.getOrderTradeSource(),
                commonLocalService.getCurrentDate(),
                requestDTO.getRefundType(),
                config.getAccountId(),
                config.getPlatformUserNo(),
                config.getUserId());

        log.info("RefundDispatchLocalService->substituteRefund result:projectId={},refundOrder={}", requestDTO.getProjectId(),refundOrder);
        return refundOrder.getId();
    }

    public Long refundOrderQuery(String orgRequestNo) {
        RefundOrder refundOrder = refundOrderMapperExt.selectByOrgRequestNo(orgRequestNo);
        return refundOrder == null? null:refundOrder.getId();
    }
}
